#ifndef PIXEL_H_INCLUDED
#define PIXEL_H_INCLUDED

#include "common.h"
#include <math.h>
#include <SDL.h>

//! \brief RGB color structure
typedef struct
{
    Uint8 r;    //!< Red Chroma Key
    Uint8 g;    //!< Green Chroma Key
    Uint8 b;    //!< Blue Chroma Key
} Pixel;

//! \brief XYZ color structure
typedef struct
{
    double x;   //!< x Chroma Key
    double y;   //!< y Chroma Key
    double z;   //!< z Chroma Key
} PixelXYZ;

//! \brief HSI color structure
typedef struct
{
    Uint8 H;   //!< Hue
    Uint8 S;   //!< Saturation
    Uint8 I;   //!< Value/Intensity
} PixelHSI;

//! \brief Lab color structure
typedef struct
{
    double L;   //!< Luminance
    double a;   //!< a Chroma Key
    double b;   //!< b Chroma Key
} PixelLab;

//! \brief Lab conversion sub function
inline double fxyz (double t)
{return t>0.00885645 ? pow(t,0.3333) : (7.787037 * t + 0.137931);}

PixelXYZ RGBtoXYZ (Pixel px);
PixelLab XYZtoLab (PixelXYZ px);
PixelXYZ LabtoXYZ (PixelLab px);
Pixel XYZtoRGB (PixelXYZ px);

PixelHSI RGBtoHSI (Pixel px);

//! \brief Transcodes RGB to Lab
//!
//! \param px A Pixel in RGB format
//! \return A Pixel in Lab format
//!
//!
inline PixelLab RGBtoLab (Pixel px) {return XYZtoLab(RGBtoXYZ(px));}

//! \brief Transcodes Lab to RGB
//!
//! \param px A Pixel in Lab format
//! \return A Pixel in RGB format
//!
//!
inline Pixel LabtoRGB (PixelLab px) {return XYZtoRGB(LabtoXYZ(px));}

PixelLab weightedAverage(PixelLab pxl1, double c1, PixelLab pxl2, double c2);
inline Uint8 IProximity(PixelHSI px1, PixelHSI px2) {return abs(px1.I - px2.I);}


#endif // PIXEL_H_INCLUDED
